# Clean workspace and load dependencies
rm(list = ls())
library(tidyr)
library(dplyr)
library(plotly)
library(ggplot2)
library(knitr)
library(lubridate)
# Function to load Xsense data (and convert time to seconds)
LoadXsenseData <- function(directory) {
# directory <- "../Data/20240419_104713"
files <- list.files(path = directory, full.names = TRUE) # Searches each marker file
data_list <- lapply(files, function(file) { # creates a list storing the data
data <- read.csv(file, header = TRUE, skip = 10) # reads each cvs file
# data$TimeS <- (data$SampleTimeFine / 1e6) - (data$SampleTimeFine[1] / 1e6) # Converts time to seconds
return(data)
})
names(data_list) <- paste0("data", seq_along(data_list)) # Names elements to my preference
## Re-align time
min_time <- min(sapply(data_list, function(df) min(df$SampleTimeFine))) # Identify the minimum SampleTimeFine value across all data
adjusted_data_list <- lapply(data_list, function(df) { # Subtract min_time from SampleTimeFine for each dataframe in data_list
df$SampleTimeFine <- df$SampleTimeFine - min_time
return(df)
})
# This is intresting. After substracting the min_time, it seemed that longer lists had a smaller minimum time, and that all time could only differ by 1/60 of a second (or 16667 SampleTimeFine).
# Thus, equaling lists in lenght by substracting the first values of longer lists, should ensure that the times are well-alligned
# Removing first elements of longer list
# Find the minimum number of rows among all dataframes
min_rows <- min(sapply(adjusted_data_list, nrow))
# Remove elements from the beginning of each dataframe in adjusted_data_list
adjusted_data_list <- lapply(adjusted_data_list, function(df) {
if (nrow(df) > min_rows) {
df <- df[(nrow(df) - min_rows + 1):nrow(df), , drop = FALSE] # Remove elements from the beginning
}
return(df)
})
list2env(adjusted_data_list, envir = .GlobalEnv) # Unpack the list into the global environment
# Define Markers dataframe
markers <- data.frame(
PacketCounter = data1$PacketCounter,
SampleTimeFine = data1$SampleTimeFine,
A_X1 = data1$FreeAcc_X,
A_X2 = data2$FreeAcc_X,
A_X3 = data3$FreeAcc_X,
A_X4 = data4$FreeAcc_X,
A_X5 = data5$FreeAcc_X,
A_Y1 = data1$FreeAcc_Y,
A_Y2 = data2$FreeAcc_Y,
A_Y3 = data3$FreeAcc_Y,
A_Y4 = data4$FreeAcc_Y,
A_Y5 = data5$FreeAcc_Y,
A_Z1 = data1$FreeAcc_Z,
A_Z2 = data2$FreeAcc_Z,
A_Z3 = data3$FreeAcc_Z,
A_Z4 = data4$FreeAcc_Z,
A_Z5 = data5$FreeAcc_Z
)
return(markers)
}LoadXsense
Explore Dot Data
Correct Time?
Obviously, not all IMU’s will register time on the exact same moment. Also, the amount of registrations per IMU differed: FreeAcc_X is of differing length per IMU. I suspect this to be due to the command stopping the IMU’s taking longer to reach and procces the different units.
Assuming that the time is synchronised across the IMU’s, and that absolute time is expressed in SampleTimeFine, it would be usefull to(1) Temporally realigning the data (2) Convert time to a more human readable format
Since time is given in microseconds, dividing by 1e6 converts it to seconds. It would be usefull to define t0 as the lowest value, and substract it from all other values. data\(TimeS <- (data\)SampleTimeFine / 1e6) - (data$SampleTimeFine[1] / 1e6)
Temporally realigning data is more work. See the code below for my inplementation where I assumed that similar values of SampleTimeFine indicate similar temporality.
Code for loading the data
markers <- LoadXsenseData("../Data/20240419_104713") # Execute function loading data
# Plots for A_X
plot <- plot_ly()
for (i in 1:5) { # Add traces for each A_X column with different colors
plot <- plot %>%
add_trace(data = markers, x = ~SampleTimeFine, y = as.formula(paste0("~A_X", i)),
type = 'scatter', mode = 'lines', name = paste("marker", i))
}
# Customize layout
plot_A_X <- plot %>%
layout(xaxis = list(title = "Sample Time Fine"),
yaxis = list(title = "Acceleration"),
title = "Acceleration vs. Sample Time Fine")
# Plots for A_Y
plot_A_Y <- plot_ly()
for (i in 1:5) { # Add traces for each A_Y column with different colors
plot_A_Y <- plot_A_Y %>%
add_trace(data = markers, x = ~SampleTimeFine, y = as.formula(paste0("~A_Y", i)),
type = 'scatter', mode = 'lines', name = paste("marker", i))
}
# Customize layout
plot_A_Y <- plot_A_Y %>%
layout(xaxis = list(title = "Sample Time Fine"),
yaxis = list(title = "Acceleration"),
title = "Acceleration vs. Sample Time Fine (A_Y)")
# Plots for A_Z
plot_A_Z <- plot_ly()
for (i in 1:5) { # Add traces for each A_Z column with different colors
plot_A_Z <- plot_A_Z %>%
add_trace(data = markers, x = ~SampleTimeFine, y = as.formula(paste0("~A_Z", i)),
type = 'scatter', mode = 'lines', name = paste("marker", i))
}
# Customize layout
plot_A_Z <- plot_A_Z %>%
layout(xaxis = list(title = "Sample Time Fine"),
yaxis = list(title = "Acceleration"),
title = "Acceleration vs. Sample Time Fine (A_Z)")